// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.


namespace Runtime_106546;

using System;
using System.Numerics;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.Arm;
using System.Runtime.Intrinsics.X86;
using Xunit;

public class Runtime_106546
{
    [ConditionalFact(typeof(Dp), nameof(Dp.IsSupported))]
    public static void TestDotProductThrows()
    {
        Assert.Throws<ArgumentOutOfRangeException>(() => new Runtime_106546().DotProduct());
    }

    [ConditionalFact(typeof(AdvSimd), nameof(AdvSimd.IsSupported))]
    public static void TestShiftRightThrows()
    {
        Assert.Throws<ArgumentOutOfRangeException>(() => new Runtime_106546().ShiftRight());
    }

    [ConditionalFact(typeof(Avx2), nameof(Avx2.IsSupported))]
    public static void TestAvxGatherThrows()
    {
        Assert.Throws<ArgumentOutOfRangeException>(() => new Runtime_106546().GatherVector128());
        Assert.Throws<ArgumentOutOfRangeException>(() => new Runtime_106546().GatherVector256());
        Assert.Throws<ArgumentOutOfRangeException>(() => new Runtime_106546().GatherMaskVector128());
        Assert.Throws<ArgumentOutOfRangeException>(() => new Runtime_106546().GatherMaskVector256());
    }

    // Generated by Fuzzlyn v2.2 on 2024-08-17 15:13:27
    // Run on Arm64 MacOS
    // Seed: 17566447992392941035-vectort,vector64,vector128,armadvsimd,armadvsimdarm64,armaes,armarmbase,armarmbasearm64,armcrc32,armcrc32arm64,armdp,armrdm,armrdmarm64,armsha1,armsha256
    // Reduced from 52.5 KiB to 0.7 KiB in 00:00:21
    // Debug: Throws 'System.ArgumentOutOfRangeException'
    // Release: Runs successfully
    private void DotProduct()
    {
        var vr4 = Vector64.Create<int>(0);
        var vr5 = Vector64.Create<sbyte>(0);
        var vr6 = Vector64.Create<sbyte>(0);
        var vr3 = Dp.DotProductBySelectedQuadruplet(vr4, vr5, vr6, 7);
        Console.WriteLine(vr3);
    }

    private struct S1
    {
        public byte byte_1;
    }

    // Found by Antigen
    private void ShiftRight()
    {
        Vector64<float> floatVec = Vector64.Create(1f);
        Vector64<double> doubleVec = Vector64.CreateScalar((double)82);
        Vector64<int> intVec = Vector64.Create(1, 1);
        Vector128<long> longVec = Vector128<long>.AllBitsSet;
        S1 s1 = new S1();

        for (int i = 0; i < 3; i++)
        {
            Vector64.Shuffle(floatVec += Vector64.AsSingle(doubleVec), AdvSimd.ShiftRightLogicalNarrowingLower(longVec, s1.byte_1) & (intVec - intVec)* 15*4);
        }

        Console.WriteLine(floatVec);
    }

    private unsafe void GatherVector128()
    {
        Vector128<int> indices = Vector128.Create(0, 1, 2, 3);
        int[] data = new int[]{1, 2, 3, 4};

        fixed (int* ptr = data)
        {
            Console.WriteLine(Avx2.GatherVector128(ptr, indices, 0));
        }
    }

    private unsafe void GatherVector256()
    {
        Vector256<long> indices = Vector256.Create(0L, 1L, 2L, 3L);
        long[] data = new long[]{1L, 2L, 3L, 4L};

        fixed (long* ptr = data)
        {
            Console.WriteLine(Avx2.GatherVector256(ptr, indices, 3));
        }
    }

    private unsafe void GatherMaskVector128()
    {
        Vector128<int> source = Vector128<int>.Zero;
        Vector128<int> indices = Vector128.Create(0, 1, 2, 3);
        Vector128<int> mask = Vector128<int>.AllBitsSet;
        int[] data = new int[]{1, 2, 3, 4};

        fixed (int* ptr = data)
        {
            Console.WriteLine(Avx2.GatherMaskVector128(source, ptr, indices, mask, 5));
        }
    }

    private unsafe void GatherMaskVector256()
    {
        Vector256<long> source = Vector256<long>.Zero;
        Vector256<long> indices = Vector256.Create(0L, 1L, 2L, 3L);
        Vector256<long> mask = Vector256<long>.AllBitsSet;
        long[] data = new long[]{1L, 2L, 3L, 4L};

        fixed (long* ptr = data)
        {
            Console.WriteLine(Avx2.GatherMaskVector256(source, ptr, indices, mask, 7));
        }
    }
}
